package br.com.felix.dbm.ui;

import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextField;

import br.com.felix.dbm.controller.ColumnController;
import br.com.felix.dbm.controller.TableController;
import br.com.felix.dbm.database.Table;
import br.com.felix.dbm.log.Logger;
import br.com.felix.dbm.ui.components.DatabaseNameKeyAdapter;
import br.com.felix.dbm.ui.components.ForeignKeyDialog;
import br.com.felix.dbm.ui.components.ImportFromJavaDialog;
import br.com.felix.dbm.ui.components.TableNameListener;

/**
 * User interface for a database table.
 * */
public class TableUi extends JScrollPane {

	private static final long serialVersionUID = 5283129428104980017L;

	private static Logger logger = Logger.getLogger(TableUi.class);
	
	private JTextField txtTableName = new JTextField();
	private JButton btnAddNewColumn = new JButton("+");
	private JButton btnAddForeignKey = new JButton("FK");
	private JButton btnImportFromJava = new JButton("java");

	private JPanel mainPanel = new JPanel();
	private JPanel fatherPanel = new JPanel();
	private TableNameKeyAdapter tableNameKeyAdapter = new TableNameKeyAdapter();

	private TableController tableController;


	public TableUi() {
		configureDefaults();
	}



	private void configureDefaults() {
		setHorizontalScrollBarPolicy(HORIZONTAL_SCROLLBAR_AS_NEEDED);
		setVerticalScrollBarPolicy(VERTICAL_SCROLLBAR_AS_NEEDED);
		mainPanel.setLayout(new GridBagLayout());
		fatherPanel.setBorder(BorderFactory.createRaisedBevelBorder());
		fatherPanel.setLayout(new GridBagLayout());
		GridBagConstraints gbc = new GridBagConstraints();
		int border = Style.getTableBorder();
		gbc.insets = new Insets(border, border, border, border);
		fatherPanel.add(mainPanel, gbc);
		setViewportView(fatherPanel);

		// componentes
		txtTableName.addKeyListener(tableNameKeyAdapter);
		txtTableName.addKeyListener(new KeyAdapter() {
			@Override
			public void keyReleased(KeyEvent e) {
				e.consume();
				tableController.setName(txtTableName.getText());
			}
		});
		txtTableName.setFont(Style.getTitleFont());
		txtTableName.setPreferredSize(new Dimension(440,30));
		
		btnAddNewColumn.addMouseListener(new AddColumnMouseListener());
		btnAddForeignKey.addMouseListener(new AddForeignKeyMouseAdapter());
		btnImportFromJava.addMouseListener(new ImportFromJavaMouseAdapter());
		btnAddNewColumn.setPreferredSize(Style.getSmallButtonSize());
		btnAddForeignKey.setPreferredSize(Style.getSmallButtonSize());
		btnImportFromJava.setPreferredSize(Style.getSmallWideButtonSize());
	}



	private void redoLayout() {
		logger.debug("Redoing layout for table", toString());
		mainPanel.removeAll();

		List<ColumnUi> lstColumnsUi = new ArrayList<ColumnUi>();
		Table table = tableController.getModel();
		txtTableName.setText(table.getName());
		Set<ColumnController> lstColumnControllers = tableController.getColumnControllers();
		ColumnUi foreignKeyView;
		for (ColumnController columnController : lstColumnControllers) {
			foreignKeyView = columnController.getViewForTable(this);
			if (foreignKeyView == null) {
				lstColumnsUi.add(columnController.getView());
			}
			else {
				lstColumnsUi.add(foreignKeyView);
			}
		}

		int size = lstColumnControllers.size();
		if (size > 0) {
			//Dimension mainPanelPreferredSize = new Dimension(480, 30 * size + 140);
			//mainPanel.setPreferredSize(mainPanelPreferredSize);
			//mainPanel.setMinimumSize(mainPanelPreferredSize);
			//Dimension scrollPanePreferredSize = new Dimension(500, 30 * size + 160);
			//setPreferredSize(scrollPanePreferredSize);
			//setMinimumSize(scrollPanePreferredSize);
			validate();
			if(getParent()!=null){
				getParent().validate();
			}
		}
		GridBagConstraints gbc = new GridBagConstraints();
		gbc.fill = GridBagConstraints.NONE;
		gbc.anchor = GridBagConstraints.NORTHWEST;
		gbc.gridx = 0;
		gbc.gridy = 0;
		gbc.gridwidth = 2;
		mainPanel.add(txtTableName, gbc);
		gbc.insets = new Insets(2, 0, 5, 0);
		for (ColumnUi coluna : lstColumnsUi) {
			logger.debug("Adding column",coluna.toString());
			gbc.gridy++;
			mainPanel.add(coluna, gbc);
			coluna.validate();
		}
		gbc.gridwidth = 1;
		gbc.gridy++;
		gbc.fill = GridBagConstraints.NONE;
		gbc.insets = new Insets(15, 0, 0, 0);
		JPanel panelButtons = new JPanel();
		panelButtons.setLayout(new GridBagLayout());
		GridBagConstraints gbc2 = new GridBagConstraints();
		gbc2.anchor = GridBagConstraints.WEST;
		gbc2.gridx=0;
		gbc2.gridy=0;
		panelButtons.add(btnAddNewColumn,gbc2);
		gbc2.gridx=1;
		panelButtons.add(btnAddForeignKey,gbc2);
		gbc2.gridx=2;
		gbc2.insets = new Insets(0,260,0,0);
		gbc2.anchor = GridBagConstraints.EAST;
		panelButtons.add(btnImportFromJava, gbc2);
		mainPanel.add(panelButtons, gbc);
		UiUtil.recursiveValidate(mainPanel);
	}

	class TableNameKeyAdapter extends DatabaseNameKeyAdapter {
		public List<TableNameListener> lstTableNameListeners = new ArrayList<TableNameListener>();



		@Override
		public void afterKeyReleased() {
			for (TableNameListener tableNameListener : lstTableNameListeners) {
				tableNameListener.tableNameChanged(databaseName);
			}
		}
	}



	public void addColumn(ColumnController columnController) {
		remove(btnAddNewColumn);
		TableNameListener tableNameListener = new TableNameListener(columnController);
		tableNameKeyAdapter.lstTableNameListeners.add(tableNameListener);
	}

	class AddColumnMouseListener extends MouseAdapter {
		@Override
		public void mouseReleased(MouseEvent e) {
			tableController.addColumn();
			tableController.updateView();
		}
	}

	class AddForeignKeyMouseAdapter extends MouseAdapter {
		@Override
		public void mouseReleased(MouseEvent e) {
			ForeignKeyDialog fkDialog = new ForeignKeyDialog(tableController);
			fkDialog.setVisible(true);
			fkDialog.toFront();
		}
	}

	class ImportFromJavaMouseAdapter extends MouseAdapter{
		
		public ImportFromJavaMouseAdapter(){
		}
		
		@Override
		public void mouseReleased(MouseEvent e) {
			ImportFromJavaDialog ijDialog = FeatureFactory.makeImportFromJavaDialog(TableUi.this.tableController);
			ijDialog.setVisible(true);
			ijDialog.toFront();
		}
	}

	public void updateView() {
		redoLayout();
	}



	public void setTableController(TableController tableController) {
		this.tableController = tableController;
	}



	public void removeColumn(ColumnController cc) {
		Iterator<TableNameListener> it = tableNameKeyAdapter.lstTableNameListeners.iterator();
		TableNameListener tnl;
		while (it.hasNext()) {
			tnl = it.next();
			if (tnl.getColumnController().equals(cc)) {
				it.remove();
			}
		}
	}



	@Override
	public synchronized void addMouseListener(MouseListener l) {
		mainPanel.addMouseListener(l);
	}

	
	public String toString(){
		return "TableUi for " + tableController.getModel().getName();
	}

}
